home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Libraries / VideoToolbox 94.11.17 / Demos / FlickeringGrating.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-17  |  6.7 KB  |  218 lines  |  [TEXT/KAHL]

  1. /*
  2. FlickeringGrating.c
  3. This demo displays a research-grade visual stimulus. If you just want to know
  4. how to load the clut and display a pattern, then you should start by reading
  5. Grating.c, which is much shorter and simpler.
  6. Copyright (c) 1989-1993 Denis G. Pelli
  7. HISTORY:
  8. 11/89     Lan & Denis wrote it.
  9. 23.1.90    dgp        Use second screen only if available.
  10. 4/9/90    dgp        Changed WindowPtr to CWindowPtr. Made big arrays static. Reduced
  11.                 default memory allocation to 1 megabyte. Use any 8-bit screen,
  12.                 preferably not the main screen.
  13. 4/23/90    dgp        Added optional timing. Centered the image. Left clut entries 0 and 
  14.                 clutSize-1 alone, so background doesn't flash. Asked if ISR Video 
  15.                 Attenuator is present.
  16. 10/11/90 dgp    Added fpu test.
  17. 10/29/90 dgp    Added CenterRectInRect().
  18. 10/30/90 dgp    Changed call to SetLuminances() to SetLuminancesAndRange() so that
  19.                 the range is now kept fixed throughout all the frames, to avoid
  20.                 flashes.
  21. 8/24/91    dgp        Made compatible with THINK C 5.0.
  22.                 If possible, use ReadLuminanceRecord().
  23. 3/10/92    dgp        include mc68881.h
  24. 4/26/92    dgp        RestoreCluts().
  25. 8/27/92    dgp        replace SysEnvirons() by Gestalt()
  26. 12/30/92 dgp    made more like Filter, using a small console so that, if necessary,
  27.                 both the console and the grating will fit on the main monitor.
  28. 2/7/93    dgp        replaced SetOnePixel by SetPixelsQuickly
  29. 7/7/93    dgp        added code for compatibility with Radius PowerView, a SCSI video box.
  30. 9/5/94 dgp removed assumption in printf's that int==short.
  31. 11/17/94 dgp Josh Solomon reported a stack overflow, so I added a calls to StackGrow
  32. and assert.
  33. */
  34. #include "VideoToolbox.h"
  35. #include "Luminance.h"
  36. #include <math.h>
  37. #include <assert.h>
  38. #if (THINK_C || THINK_CPLUS)
  39.     #include <console.h>
  40.     #include <profile.h>
  41. #endif
  42. #if UNIVERSAL_HEADERS
  43.     #include <LowMem.h>
  44. #else
  45.     #define LMGetMBarHeight() (* (short *) 0x0BAA)
  46.     #define LMSetMBarHeight(MBarHeightValue) ((* (short *) 0x0BAA) = (MBarHeightValue))
  47. #endif
  48.  
  49. #define SIZE         300            // size of grating, in pixels
  50. #define TMAX        3*67        // duration, in frames, typically at 67 Hz
  51. #define REPETITIONS    5            // Number of times to repeat the animation
  52. #define PROFILE        0            // optionally, report timing
  53.  
  54. void main(void);
  55. void FlickeringGrating(void);
  56. typedef struct{
  57.     ColorSpec table[256];
  58. }ColorSpecTable;
  59.  
  60. void main(void)
  61. {
  62.     StackGrow(10000+2*SIZE*sizeof(double)+sizeof(LuminanceRecord)+TMAX*4);
  63.     Require(gestalt8BitQD);
  64.     FlickeringGrating();
  65. }
  66.     
  67. void FlickeringGrating(void)
  68. {
  69.     register int i;
  70.     int j,tmax,pixelSize,clutSize;
  71.     double fX[SIZE],fY[SIZE];
  72.     double LMid,LMin,LMax,dL,a,contrast;
  73.     WindowPtr window=NULL, oldWindow=NULL;
  74.     GDHandle device=NULL;
  75.     LuminanceRecord LR,*LP=&LR;
  76.     ColorSpecTable *tables[TMAX];    // an array of pointers to ColorSpec tables
  77.     char string[100];
  78.     Rect r;
  79.     Boolean yes;
  80.     RgnHandle rgn;
  81.     
  82.     assert(StackSpace()>4000);
  83.     #if PROFILE
  84.         InitProfile(200,3);    /* only needed if you want timing info */
  85.         _profile=0;
  86.     #endif
  87.     /* INITIALIZE QuickDraw */
  88.     #if (THINK_C || THINK_CPLUS)
  89.         console_options.title="\pFlickeringGrating";
  90.         console_options.top = 20;
  91.         console_options.nrows = 4;
  92.         printf("\n");
  93.     #else
  94.         InitGraf(&qd.thePort);
  95.         InitFonts();
  96.         InitWindows();
  97.         InitCursor();
  98.     #endif
  99. //    HideMenuBar();
  100.     printf("\n");    // make sure that oldWindow is the console
  101.     GetPort(&oldWindow);
  102.     #if __MWERKS__
  103.         MoveWindow(oldWindow,0,LMGetMBarHeight()+19,1);
  104.     #endif
  105.     printf("Welcome to FlickeringGrating.\n");
  106.     for(i=8;i>=0;i--){
  107.         // look for a screen with 8-bit pixels.
  108.         device=GetScreenDevice(i);
  109.         if(device == NULL)continue;
  110.         pixelSize=(*(*device)->gdPMap)->pixelSize;
  111.         if(pixelSize==8)break;
  112.     }
  113.     if(pixelSize!=8 && NewPaletteManager())for(i=8;i>=0;i--){
  114.         // try to force a screen to 8-bit pixels.
  115.         device=GetScreenDevice(i);
  116.         if(device == NULL)continue;
  117.         SetDepth(device,8,1<<gdDevType,1);
  118.         pixelSize=(*(*device)->gdPMap)->pixelSize;
  119.         if(pixelSize==8)break;
  120.     }
  121.     if(device==NULL || pixelSize != 8) PrintfExit("Sorry, I require 8 bits/pixel.\n");
  122.     window = GDOpenWindow1(device);
  123.     sprintf(string,"LuminanceRecord%d.h",i);
  124.     i=ReadLuminanceRecord(string,LP,0);    /* try to read correct file */
  125.     if(i<=0){
  126.         #include "LuminanceRecord1.h"
  127.     }
  128.     printf("Using luminance calibration for screen %d calibrated %s by %s.\n"
  129.         ,(int)LP->screen,LP->date,LP->notes);
  130.     yes=Choose(0,"Have you installed an ISR Video Attenuator?\n",noYes,2);
  131.     if(!yes){
  132.         LP->r=0.0;
  133.         LP->g=1.0;
  134.         LP->b=0.0;
  135.     }
  136.     #if PROFILE
  137.         _profile=1;
  138.     #endif
  139.  
  140.     /* load clut with linear gray scale */
  141.     // We'll leave clut entries 0 (white) and clutSize-1 (black) alone,
  142.     // since they are used heavily by Apple's stuff. Window frames
  143.     // will mostly look normal if we leave those two entries alone.
  144.     clutSize=GDClutSize(device);
  145.     SetLuminances(device,LP,1,clutSize-2,LP->LMin,LP->LMax);
  146.         
  147.     /* Display a sinusoid with a gaussian envelope */
  148.     // Compute the image.
  149.     SetPort(window);
  150.     PmBackColor(1+(long)(0.5+(clutSize-3)*0.5));
  151.     EraseRect(&window->portRect);
  152.     SetRect(&r,0,0,SIZE,SIZE);
  153.     CenterRectInRect(&r,&window->portRect);
  154.     for(i=0;i<SIZE;i++){
  155.         a=(i-SIZE/2)/(SIZE/6.);
  156.         fY[i]=exp(-a*a);
  157.         fX[i]=fY[i]*sin((i-SIZE/2)*(2.0*PI/80.0));
  158.     }
  159.     for(j=0;j<SIZE;j++){
  160.         unsigned long row[SIZE];
  161.         for(i=0;i<SIZE;i++) row[i]=1+(long)(0.5+(clutSize-3)*0.5*(1.0+fY[j]*fX[i]));
  162.         SetPixelsQuickly(r.left,j+r.top,row,SIZE);
  163.     }
  164.     // These bits of conditional code force the Radius PowerView
  165.     // to update the screen from the video buffer in memory.
  166.     #if 0    // No good; causes undesired color translation.
  167.         oldDevice=GetGDevice();
  168.         SetGDevice(device);
  169.         CopyBits((BitMap *)*((CGrafPtr)window)->portPixMap
  170.             ,(BitMap *)*((CGrafPtr)window)->portPixMap
  171.             ,&r,&r,srcCopy,NULL);
  172.         SetGDevice(oldDevice);
  173.     #endif
  174.     #if 1    // Ok, but I don't actually want to scroll.
  175.         rgn=NewRgn();
  176.         ScrollRect(&r,0,1,rgn);
  177.         DisposeRgn(rgn);
  178.     #endif
  179.     // Allocate ColorSpec tables, one for each frame
  180.     for(i=0;i<TMAX;i++){
  181.         tables[i]= (ColorSpecTable *)NewPtr(sizeof(ColorSpecTable));
  182.         if(tables[i]==NULL){
  183.             printf("Only room for %d lookup tables (one per frame) ... continuing.\n",i);
  184.             break;
  185.         }
  186.     }
  187.     tmax=i;
  188.     // Compute lookup tables.
  189.     LMid=(LP->LMax+LP->LMin)/2.0;
  190.     contrast=(LP->LMax-LP->LMin)/(LP->LMax+LP->LMin);
  191.     LMax=LMid*(1.0+contrast);
  192.     LMin=LMid*(1.0-contrast);
  193.     for(i=0;i<tmax;i++){
  194.         a=6.0*(i-tmax/2)/tmax;
  195.         dL=LMid*contrast*exp(-a*a)*sin((i-tmax/2)*(2.0*PI*3.0*0.015));
  196.         SetLuminancesAndRange(NULL,LP,1,clutSize-2,LMid-dL,LMid+dL,LMin,LMax);
  197.         *tables[i]= *(ColorSpecTable *)LP->table;
  198.     }
  199.     printf("Now displaying the animation ...\n");
  200.     for(j=0;j<REPETITIONS;j++){
  201.         for(i=0;i<tmax;i++){
  202.             // This is a thinly disguished call to GDSetEntries.
  203.             LoadLuminances(device,(LuminanceRecord *) tables[i],1,clutSize-2);
  204.         }
  205.     }
  206.     #if PROFILE
  207.         _profile=0;
  208.     #endif
  209.     for(i=0;i<tmax;i++)DisposPtr((Ptr)tables[i]);
  210.     SetPort(oldWindow);
  211.     GDDisposeWindow1(window);
  212.     RestoreCluts();
  213. //    ShowMenuBar();
  214.     #if !PROFILE
  215.         abort();
  216.     #endif
  217. }
  218.